package com.jerry.wschat.web.websocket;

import com.alibaba.fastjson.JSONObject;
import com.jerry.wschat.model.vo.MessageVO;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.websocket.Session;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Jerry.Wu
 * @description:
 * @date 2018/9/12 14:58
 */
@Slf4j
public class WebSocketUtils {

    private static Logger logger = LoggerFactory.getLogger(WebSocketUtils.class);

    public static volatile int onlineCount = 0;

    public static Map<Integer, List<Session>> sessionMap = new ConcurrentHashMap<>();

    public static void put(Integer userId, Session session) {
        List<Session> sessionList;
        if (hasConnection(userId)) {
            get(userId).add(session);
        } else {
            sessionList = get(userId);
            if (sessionList == null) {
                sessionList = new ArrayList<>();
            }
            sessionList.add(session);
            sessionMap.put(userId, sessionList);
        }
    }

    public static List<Session> get(Integer userId) {
        return sessionMap.get(userId);
    }

    public static void remove(Integer userId, Session session) {
        if (!hasConnection(userId)) {
            return;
        }
        List<Session> sessionList = sessionMap.get(userId);
        sessionList.remove(session);
        if (sessionList.size() == 0) {
            sessionList = null;
        }
    }

    /**
     * 单体发送消息
     * @param userId
     * @param messageVO
     */
    public static void sendMessage(Integer userId, MessageVO messageVO) {
        if (hasConnection(userId)) {
            List<Session> sessionList = get(userId);
            try {
                for (Session session : sessionList) {
                    session.getBasicRemote().sendText(JSONObject.toJSONString(messageVO));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            throw new NullPointerException();
        }
    }

    /**
     * 群体发送消息
     * @param userIds
     * @param messageVO
     */
    public static void sendMessage(List<Integer> userIds, MessageVO messageVO) {
        for (Integer userId : userIds) {
            sendMessage(userId, messageVO);
        }
    }

    /**
     * 发送消息至所有人
     * @param messageVO
     */
    public static void sendMessageAll(MessageVO messageVO) {
        sessionMap.keySet().forEach(userId->{
            // 不发给自己
            if (!(userId.equals(messageVO.getFromUserVO().getUserId()))) {
                sendMessage(userId, messageVO);
            }
        });
    }

    public static boolean hasConnection(Integer userId) {
        if (!sessionMap.containsKey(userId)) {
            return false;
        }
        List<Session> sessionList = get(userId);
        if (sessionList == null || sessionList.size() == 0) {
            return false;
        }
        return true;
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        onlineCount++;
        logger.info("有新连接加入！当前在线人数为：{}", onlineCount);
    }

    public static synchronized void subOnlineCount() {
        onlineCount--;
        logger.info("有一连接关闭！当前在线人数为：{}", onlineCount);
    }

}
